package com.beauty.product.controller;

import com.beauty.product.dto.PageResponse;
import com.beauty.product.dto.ProductAttributeDto;
import com.beauty.product.dto.ProductDto;
import com.beauty.product.dto.ProductImageDto;
import com.beauty.product.dto.ProductQueryParam;
import com.beauty.product.result.Result;
import com.beauty.product.service.ProductService;
import com.beauty.product.service.ProductElasticsearchService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 商品控制器
 * <p>
 * 该控制器负责处理与商品相关的所有HTTP请求，包括商品的创建、查询、更新、删除等操作。
 * 同时还提供商品图片和属性的管理，以及与Elasticsearch搜索引擎的集成功能。
 * </p>
 * 
 * @author beauty-dev
 * @version 1.0
 */
@RestController
@RequestMapping("/api/product")
@RequiredArgsConstructor
@Slf4j
public class ProductController {

    /**
     * 商品服务，提供商品的核心业务逻辑处理
     */
    private final ProductService productService;
    
    /**
     * 商品Elasticsearch服务，提供商品的搜索功能
     */
    private final ProductElasticsearchService productElasticsearchService;

    /**
     * 创建新商品
     * 
     * @param productDto 商品数据传输对象，包含商品的详细信息
     * @return 返回创建成功的商品信息
     */
    @PostMapping
    public Result<ProductDto> createProduct(@Valid @RequestBody ProductDto productDto) {
        return Result.success(productService.createProduct(productDto));
    }

    /**
     * 根据ID获取商品详情
     * 
     * @param id 商品ID
     * @return 返回指定ID的商品详细信息
     */
    @GetMapping("/{id}")
    public Result<ProductDto> getProduct(@PathVariable String id) {
        return Result.success(productService.getProductById(id));
    }

    /**
     * 根据SKU获取商品详情
     * 
     * @param sku 商品SKU编码
     * @return 返回指定SKU的商品详细信息
     */
    @GetMapping("/sku/{sku}")
    public Result<ProductDto> getProductBySku(@PathVariable String sku) {
        return Result.success(productService.getProductBySku(sku));
    }

    /**
     * 根据查询参数搜索商品
     * 
     * @param param 查询参数对象，包含关键词、分类、价格范围等
     * @return 返回符合条件的商品分页结果
     */
    @GetMapping("/search")
    public Result<Page<ProductDto>> searchProducts(ProductQueryParam param) {
        return Result.success(productService.getProducts(param));
    }

    /**
     * 获取指定分类下的所有商品
     * 
     * @param categoryId 分类ID
     * @param pageNum 页码，默认为1
     * @param pageSize 每页数量，默认为10
     * @return 返回分类下的商品分页结果
     */
    @GetMapping("/category/{categoryId}")
    public Result<Page<ProductDto>> getProductsByCategory(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        return Result.success(productService.getProductsByCategory(categoryId, pageNum, pageSize));
    }

    /**
     * 获取热门商品列表
     * 
     * @param limit 返回商品数量，默认为10
     * @return 返回热门商品列表
     */
    @GetMapping("/hot")
    public Result<List<ProductDto>> getHotProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getHotProducts(limit));
    }

    /**
     * 获取新品列表
     * 
     * @param limit 返回商品数量，默认为10
     * @return 返回新品商品列表
     */
    @GetMapping("/new")
    public Result<List<ProductDto>> getNewProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getNewProducts(limit));
    }

    /**
     * 获取推荐商品列表
     * 
     * @param limit 返回商品数量，默认为10
     * @return 返回推荐商品列表
     */
    @GetMapping("/recommended")
    public Result<List<ProductDto>> getRecommendedProducts(
            @RequestParam(defaultValue = "10") int limit) {
        return Result.success(productService.getRecommendedProducts(limit));
    }

    /**
     * 更新商品信息
     * 
     * @param id 商品ID
     * @param productDto 更新的商品信息
     * @return 返回更新后的商品详情
     */
    @PutMapping("/{id}")
    public Result<ProductDto> updateProduct(
            @PathVariable String id,
            @Valid @RequestBody ProductDto productDto) {
        return Result.success(productService.updateProduct(id, productDto));
    }

    /**
     * 删除商品
     * 
     * @param id 要删除的商品ID
     * @return 返回操作结果
     */
    @DeleteMapping("/{id}")
    public Result<Void> deleteProduct(@PathVariable String id) {
        productService.deleteProduct(id);
        return Result.success();
    }

    /**
     * 商品上下架操作
     * 
     * @param id 商品ID
     * @param isPublished 是否上架，true表示上架，false表示下架
     * @return 返回操作结果
     */
    @PutMapping("/{id}/publish")
    public Result<Void> publishProduct(
            @PathVariable String id,
            @RequestParam Boolean isPublished) {
        productService.publishProduct(id, isPublished);
        return Result.success();
    }

    /**
     * 为商品添加图片
     * 
     * @param productId 商品ID
     * @param imageDto 图片信息
     * @return 返回添加成功的图片信息
     */
    @PostMapping("/{productId}/images")
    public Result<ProductImageDto> addProductImage(
            @PathVariable String productId,
            @Valid @RequestBody ProductImageDto imageDto) {
        return Result.success(productService.addProductImage(productId, imageDto));
    }

    /**
     * 获取商品的所有图片
     * 
     * @param productId 商品ID
     * @return 返回商品图片列表
     */
    @GetMapping("/{productId}/images")
    public Result<List<ProductImageDto>> getProductImages(@PathVariable String productId) {
        return Result.success(productService.getProductImages(productId));
    }

    /**
     * 删除商品图片
     * 
     * @param imageId 图片ID
     * @return 返回操作结果
     */
    @DeleteMapping("/images/{imageId}")
    public Result<Void> deleteProductImage(@PathVariable Long imageId) {
        productService.deleteProductImage(imageId);
        return Result.success();
    }

    /**
     * 为商品添加属性
     * 
     * @param productId 商品ID
     * @param attributeDto 属性信息
     * @return 返回添加成功的属性信息
     */
    @PostMapping("/{productId}/attributes")
    public Result<ProductAttributeDto> addProductAttribute(
            @PathVariable String productId,
            @Valid @RequestBody ProductAttributeDto attributeDto) {
        return Result.success(productService.addProductAttribute(productId, attributeDto));
    }

    /**
     * 获取商品的所有属性
     * 
     * @param productId 商品ID
     * @return 返回商品属性列表
     */
    @GetMapping("/{productId}/attributes")
    public Result<List<ProductAttributeDto>> getProductAttributes(@PathVariable String productId) {
        return Result.success(productService.getProductAttributes(productId));
    }

    /**
     * 删除商品属性
     * 
     * @param attributeId 属性ID
     * @return 返回操作结果
     */
    @DeleteMapping("/attributes/{attributeId}")
    public Result<Void> deleteProductAttribute(@PathVariable Long attributeId) {
        productService.deleteProductAttribute(attributeId);
        return Result.success();
    }

    /**
     * 获取商品分页数据
     * <p>
     * 支持排序功能，可以指定排序字段和排序方向
     * </p>
     * 
     * @param page 页码，默认为0
     * @param size 每页数量，默认为10
     * @param sort 排序字段，默认为id
     * @param direction 排序方向，默认为desc（降序）
     * @return 返回商品分页数据
     */
    @GetMapping("/page")
    public Result<PageResponse<ProductDto>> getProductsPage(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到获取商品分页请求: page={}, size={}, sort={}, direction={}", page, size, sort, direction);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.getProductsPage(pageable);
        return Result.success(response);
    }

    /**
     * 快速搜索商品
     * <p>
     * 根据关键字对商品进行模糊查询，支持分页和排序
     * </p>
     * 
     * @param keyword 搜索关键字
     * @param page 页码，默认为0
     * @param size 每页数量，默认为10
     * @param sort 排序字段，默认为id
     * @param direction 排序方向，默认为desc（降序）
     * @return 返回搜索结果的分页数据
     */
    @GetMapping("/search/quick")
    public Result<PageResponse<ProductDto>> searchProducts(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到模糊查询请求: keyword={}, page={}, size={}", keyword, page, size);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.searchProducts(keyword, pageable);
        return Result.success(response);
    }

    /**
     * 高级搜索商品
     * <p>
     * 支持多条件组合查询，如商品名称、SKU、品牌、描述等，并支持分页和排序
     * </p>
     * 
     * @param name 商品名称（可选）
     * @param sku 商品SKU（可选）
     * @param brand 商品品牌（可选）
     * @param description 商品描述（可选）
     * @param page 页码，默认为0
     * @param size 每页数量，默认为10
     * @param sort 排序字段，默认为id
     * @param direction 排序方向，默认为desc（降序）
     * @return 返回搜索结果的分页数据
     */
    @GetMapping("/search/advanced")
    public Result<PageResponse<ProductDto>> advancedSearch(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String sku,
            @RequestParam(required = false) String brand,
            @RequestParam(required = false) String description,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "id") String sort,
            @RequestParam(defaultValue = "desc") String direction) {
        log.info("【商品服务】接收到高级搜索请求，参数: 商品名称={}, SKU={}, 品牌={}, 页码={}, 每页数量={}",
                name, sku, brand, page, size);

        Sort.Direction sortDirection = "asc".equalsIgnoreCase(direction) ? Sort.Direction.ASC : Sort.Direction.DESC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

        PageResponse<ProductDto> response = productService.advancedSearch(
                name, sku, brand, description, pageable);
        return Result.success(response);
    }

    /**
     * 同步所有商品数据到Elasticsearch
     * <p>
     * 将数据库中的所有商品数据同步到Elasticsearch搜索引擎，用于全文搜索
     * </p>
     * 
     * @return 返回同步结果信息
     */
    @PostMapping("/sync/elasticsearch")
    public Result<String> syncElasticsearch() {
        productElasticsearchService.syncAllProductsFromDB();
        return Result.success("所有产品已同步到Elasticsearch");
    }

    /**
     * 使用Elasticsearch搜索商品
     * <p>
     * 直接调用Elasticsearch进行商品搜索，支持全文搜索和分页
     * </p>
     * 
     * @param keyword 搜索关键字（可选）
     * @param page 页码，默认为0
     * @param size 每页数量，默认为10
     * @return 返回搜索结果的分页数据
     */
    @GetMapping("/es/search")
    public ResponseEntity<PageResponse<ProductDto>> searchByES(
            @RequestParam(required = false) String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        Pageable pageable = PageRequest.of(page, size);
        PageResponse<ProductDto> response = productElasticsearchService.search(keyword, pageable);
        return ResponseEntity.ok(response);
    }
}
